package com.zyfu.mybatis.demo.mybatis;

import cn.hutool.core.bean.BeanDesc;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.PropDesc;
import org.apache.ibatis.binding.MapperMethod;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Signature;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.List;

/**
 * <b>请输入名称</b>
 * <pre>
 * 描述<br/>
 * 作用：；<br/>
 * 限制：；<br/>
 * </pre>
 *
 * @author 张永福
 * @since 2024/2/18 09:32
 */
@Component
@Intercepts(
        {
                /**
                 * 拦截 Executor 的 update方法, args与 update方法的入参一致
                 * org.apache.ibatis.executor.Executor#update(org.apache.ibatis.mapping.MappedStatement, java.lang.Object)
                 */
                @Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class}),
        }
)
public class BatchInsertInterceptor implements Interceptor {
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        Object[] args = invocation.getArgs();
        MappedStatement statements = (MappedStatement) args[0];

        String id = statements.getId();
        if (!DaoMethodUtil.isBatchInsert(id)) {
            return invocation.proceed();
        }
        MapperMethod.ParamMap<?> paramMap = (MapperMethod.ParamMap<?>) args[1];
        Date date = new Date();
        setCollection(paramMap, "list", date);
        setCollection(paramMap, "entities", date);
        return invocation.proceed();
    }

    private void setCollection(MapperMethod.ParamMap<?> paramMap, String collectionName, Date date) {
        if (!paramMap.containsKey(collectionName)) {
            return;
        }
        Object collection = paramMap.get(collectionName);
        boolean instance = collection instanceof List<?>;
        if (!instance) {
            return;
        }
        List<?> list = (List<?>) collection;
        for (Object item : list) {
            BeanDesc beanDesc = BeanUtil.getBeanDesc(item.getClass());
            if (beanDesc.getProp("updateTime") != null) {
                BeanUtil.setFieldValue(item, "updateTime", date);
            }
            if (beanDesc.getProp("createTime") != null) {
                BeanUtil.setFieldValue(item, "createTime", date);
            }
        }
    }
}
